package com.cyh.blog.business.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.cyh.blog.business.enums.ArticleStatusEnum;
import com.cyh.blog.business.service.*;
import com.cyh.blog.business.vo.ArticleVo;
import com.cyh.blog.exception.CustomException;
import com.cyh.blog.persistence.beans.*;
import com.cyh.blog.persistence.mapper.BizArticleDao;
import com.cyh.blog.persistence.mapper.BizTypeDao;
import com.cyh.blog.util.ToolUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cyh
 * @since 2018-05-16
 */
@Service
public class BizArticleServiceImpl extends ServiceImpl<BizArticleDao, BizArticle> implements BizArticleService {

    @Autowired
    private  BizArticleDao bizArticleDao;

    @Autowired
    private BizTypeDao bizTypeDao;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private BizArticleLookService bizArticleLookService;

    @Autowired
    private BizArticleLoveService bizArticleLoveService;

    @Autowired
    private BizArticleTagsService bizArticleTagsService;

    @Autowired
    private BizCommentService bizCommentService;






    private final static String TAG = "articleId";


    /**
     * 分页查出文章 -> 文章的多个标签 -> 文章的唯一type  ->浏览量
     * @param articleVo
     * @return
     */
    @Override
    public PageInfo<BizArticle> selectByCondition(ArticleVo articleVo) {
            PageHelper.startPage(articleVo.getPageNumber(), articleVo.getPageSize());
        List<BizArticle> bizArticles = bizArticleDao.selectByCondition(articleVo);

        List<Integer> ids = new ArrayList<>();

        for (BizArticle ba : bizArticles){
            ids.add(ba.getId());
        }

        List<BizArticle> bizArticlesTags = bizArticleDao.selectArticleTagsByArticleId(ids);

        //合并两个内容
        Map<Integer, BizArticle> map = new LinkedHashMap<>();
        for (BizArticle article : bizArticlesTags){
            map.put(article.getId(), article);
        }

        List<BizArticle> list = new LinkedList<>();
        for (BizArticle article : bizArticles){
            BizArticle bizArticle = map.get(article.getId());
            List<BizTags> tags = bizArticle.getTags();
            article.setTags(tags);
            list.add(article);
        }

        //坑，先放入查询的，在用setList设置，否在分页信息将出错
        PageInfo pageInfo = new PageInfo(bizArticles);
        pageInfo.setList(list);
        return pageInfo;
    }


    @Override
    public BizArticle selectByKey(Integer id) {
        return bizArticleDao.selectByKey(id);
    }

    @Override
    public void insertBean(BizArticle bizArticle) {
        bizArticleDao.insertBean(bizArticle);
    }

    @Override
    public Integer insertOrUpdateBean(ArticleVo article) {
        BizArticle bizArticle = new BizArticle();
        bizArticle.setId(article.getId());
        bizArticle.setUserId(article.getUserId());
        bizArticle.setTypeId(article.getTypeId());
        bizArticle.setContent(article.getContent());
        bizArticle.setCoverImage(article.getCoverImage());
        bizArticle.setCreateTime(article.getCreateTime());
        bizArticle.setUpdateTime(article.getUpdateTime());
        bizArticle.setDescription(article.getDescription());
        bizArticle.setKeywords(article.getKeywords());
        bizArticle.setTitle(article.getTitle());
        bizArticle.setTop(article.getTop());
        if (article.isOriginal()){
            bizArticle.setOriginal(1);
        }else{
            bizArticle.setOriginal(0);
        }
        bizArticle.setStatus(article.getStatus());
        bizArticle.setRecommended(article.getRecommended());
        this.insertOrUpdate(bizArticle);
        return bizArticle.getId();
    }

    /**
     * 获取上下文章
     * @param time
     * @return
     */
    @Override
    public Map<String, BizArticle> getPreAndNext(Date time) {
        List<BizArticle> bizArticles = bizArticleDao.selectPreAndNext(time);
        Map<String, BizArticle> map = new HashMap<>();
        for (BizArticle article : bizArticles){
            if (article.getCreateTime().getTime() < time.getTime()){
                map.put("pre",article);
            }
            if (article.getCreateTime().getTime() > time.getTime()){
                map.put("next",article);
            }
        }
        return map;
    }

    /**
     * 相关文章, 根据本文章的同类别，同标签获取
     * @param bizArticle
     * @param HOT_RELATED_SIZE
     * @return
     */
    @Override
    public List<BizArticle> getRelatedArticle(BizArticle bizArticle, Integer pageSize) {
        ArticleVo articleVo = new ArticleVo();
        //同类别
        articleVo.setTypeId(bizArticle.getTypeId());
        //必须是发布的
        articleVo.setStatus(ArticleStatusEnum.PUBLISHED.getCode());
        //同标签的
        List<BizTags> tags = bizArticle.getTags();
        List<Integer> ids = new ArrayList<>();
        for (BizTags bizTags : tags) {
            ids.add(bizTags.getId());
        }
        PageHelper.startPage(1, pageSize );
        List<BizArticle> bizArticles = bizArticleDao.selectArticleByTags(ids, articleVo);
        return bizArticles;
    }

    /**
     * 获取热门文章
     * @param pageSize
     * @return
     */
    @Override
    public List<BizArticle> getHotArticle(Integer pageSize) {
        PageHelper.startPage(1, pageSize );
        List<BizArticle> list = bizArticleDao.selectHotArticle();
        return list;
    }

    /**
     * 用户给文章点赞
     * @param request
     */
    @Override
    public void parise(HttpServletRequest request) throws CustomException {
        String articleId = request.getParameter("articleId");
        String ip = ToolUtil.getClientIp(request);
        String key =ip+TAG+articleId;
        if (redisTemplate.hasKey(key)){
            throw new CustomException("一小时内只能赞一次哦");
        }
        ValueOperations<String, Object> ops= redisTemplate.opsForValue();
        ops.set(key, articleId, 1, TimeUnit.HOURS);
        BizArticleLove bizArticleLove = new BizArticleLove();
        bizArticleLove.setArticleId(Integer.parseInt(articleId));
        bizArticleLove.setCreateTime(new Date());
        bizArticleLove.setUpdateTime(new Date());
        bizArticleLove.setLoveTime(new Date());
        bizArticleLove.setUserIp(ip);
        bizArticleLoveService.insert(bizArticleLove);
    }

    /**
     * 文章搜索
     *
     * @param content
     */
    @Override
    public List<BizArticle> search(String content) {
        List<BizArticle> bizArticles = bizArticleDao.selectByTitle(content);
        return bizArticles;
    }

    /**
     * 文章删除
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeArticleById(Integer id) {
        //删除文章
        bizArticleDao.delete(new EntityWrapper<BizArticle>().eq("id", id));
        //删除查看表
        bizArticleLookService.delete(new EntityWrapper<BizArticleLook>().eq("article_id",id));
        //删除点赞表
        bizArticleLoveService.delete(new EntityWrapper<BizArticleLove>().eq("article_id", id));
        //删除标签表
        bizArticleTagsService.delete(new EntityWrapper<BizArticleTags>().eq("article_id", id));
        //删除标签表
        bizCommentService.delete(new EntityWrapper<BizComment>().eq("sid", id));
    }
}